#pragma once

#include <compl.h>
#include <dbg.h>


#include <sys/mman.h>
#include <stdlib.h>
// SAI bool_t ret_pages(void *ptr, word_t page_nr)
// {

//	 int ret = munmap(ptr, page_nr * PAGE_SIZE);
//	 if (ret != 0) return FALSE;
//	 return TRUE;
// }

// SAI void *get_pages(word_t page_nr)
// {
//	 void *mem;
//	 // int add_flag = MAP_NORESERVE;
// // RETRY:
//	 mem = mmap(NULL, page_nr * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
//	 if (mem == MAP_FAILED)
//	 {
//		 return NULL;
//		 // goto RETRY;
//	 }
//	 return mem;
// }

SAI void *page_alloc(size_t size)
{
	void *mem;
	mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
	if (mem == MAP_FAILED)
	{
		return NULL;
		// goto RETRY;
	}
	return mem;
}

SAI bool_t page_free(void *ptr, size_t size)
{
	int ret = munmap(ptr, size);
	if (ret != 0) return FALSE;
	return TRUE;
}

// extern int madvise (void *__addr, size_t __len, int __advice) __attribute__ ((__nothrow__ , __leaf__));
SAI void mark_unused_pages(void *ptr, size_t sz){
	PARAM_USED(ptr);
	PARAM_USED(sz);
	// madvise(ptr, page_nr << PAGE_SHIFT, MADV_FREE); /* MADV_FREE */															  
}			

SAI void *mark_hugepage(void *ptr, unsigned long size, const int hugepage_lvl)
{
	void *mem = mmap(ptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
	if (mem == MAP_FAILED)
	{
		//perror("Error ");
		return NULL;
	}
	if(hugepage_lvl){
		int madv_ret = madvise(ptr, size, MADV_HUGEPAGE);
		if (madv_ret)
			fprintf(stderr, "madvise failed %d\n", madv_ret);
	}
	return mem;
}
// HANDLE_MEFF(get_pages, os_alloc_pages)
// HANDLE_MEFF(ret_pages, os_decommit_pages)


// HANDLE_MEFF(mark_unused_pages, os_mark_unused_pages)

// /* 为了不依赖malloc.h 必须实现一个简单的对齐分配库,该库一般不会释放除非 已经被使用*/

// #define TINYALLOC_BLK_PGNR (1)
// typedef struct tinyalloc{
//	 struct{
//		 word_t cur_used;
//		 word_t total_size;
//		 struct tinyalloc *next;
//	 }ALIGN(CACHE_LINE_BYTES);
// }tinyalalloc_t;

// #ifdef USE_TINYALLOC

// static tinyalalloc_t * volatile __tinycur_active;

// static inline void *cac_alloc_cachealigned(word_t size){
//	 void *ptr;
//	 if (!__tinycur_active){

//	 }
//	 ptr = aligned_alloc(CACHE_LINE_BYTES, size);
//	 return ptr;
// }

// static inline void cac_free_cachealigned(void *ptr, word_t size){
//	 if (!ptr || size == 0) return;

// }
// #else
// static inline void *cac_alloc_cachealigned(word_t size){
//	 void *ptr;
//	 ptr = aligned_alloc(CACHE_LINE_BYTES, size);
//	 return ptr;
// }

// static inline void cac_free_cachealigned(void *ptr, word_t size){
//	 free(ptr);
// }
// #endif
